package com.example.mqttdemo.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mqttdemo.entity.dto.DevicesControlDto;
import com.example.mqttdemo.entity.dto.DevicesDto;
import com.example.mqttdemo.entity.pojo.DeviceCommands;
import com.example.mqttdemo.entity.pojo.Devices;
import com.example.mqttdemo.entity.pojo.devicesPageQuery;
import com.example.mqttdemo.entity.vo.DeviceCommandVO;
import com.example.mqttdemo.result.Result;
import com.example.mqttdemo.service.DeviceCommandsService;
import com.example.mqttdemo.service.DevicesService;
import com.example.mqttdemo.mapper.DevicesMapper;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;

/**
 * @author wangzihang
 * &#064;description  针对表【devices】的数据库操作Service实现
 * &#064;createDate  2025-10-19 20:01:55
 */
@Service
public class DevicesServiceImpl extends ServiceImpl<DevicesMapper, Devices>
        implements DevicesService {

    @Autowired
    private MqttClient mqttClient;

    @Autowired
    private DeviceCommandsService deviceCommandsService;

    /**
     * 添加设备
     *
     * @param devicesDto 设备信息
     * @return 添加结果信息
     */
    @Override
    public Result addDevice(DevicesDto devicesDto) {
        Devices devices = new Devices();
        // 校验设备id唯一性
        Devices device = this.getOne(new QueryWrapper<Devices>().eq("device_id", devicesDto.getDeviceId()));
        if (device != null) {
            return Result.error("设备ID已存在");
        }
        BeanUtils.copyProperties(devicesDto, devices);
        devices.setCreatedTime(LocalDateTime.now());
        devices.setUpdatedTime(LocalDateTime.now());
        boolean save = this.save(devices);
        if (!save) {
            return Result.error("添加失败");
        }
        return Result.success(devices, "添加成功");
    }

    /**
     * 分页查询设备列表
     *
     * @param page      分页参数
     * @param pageQuery 查询条件
     * @return 设备列表
     */
    @Override
    public IPage<Devices> pageDevices(IPage<Devices> page, devicesPageQuery pageQuery) {
        QueryWrapper<Devices> queryWrapper = new QueryWrapper<>();
        // 只有当 device_type 不为空时才添加查询条件
        if (pageQuery.getDeviceType() != null && !pageQuery.getDeviceType().isEmpty()) {
            queryWrapper.eq("device_type", pageQuery.getDeviceType());
        }

        // 只有当 status 不为空时才添加查询条件
        if (pageQuery.getStatus() != null && !pageQuery.getStatus().isEmpty()) {
            queryWrapper.eq("status", pageQuery.getStatus());
        }

        if (pageQuery.getLocation() != null && !pageQuery.getLocation().isEmpty())
            queryWrapper.like("location", pageQuery.getLocation());

        if (pageQuery.getDeviceName() != null && !pageQuery.getDeviceName().isEmpty())
            queryWrapper.like("device_name", pageQuery.getDeviceName());

        // 添加排序参数 createdTime 排序方向参数：order
        queryWrapper.orderByDesc("created_time");
        IPage<Devices> pageList = this.page(page, queryWrapper);
        return pageList;
    }

    /**
     * 设备控制 信息下发
     *
     * @param devicesControlDto 设备控制信息
     * @return 设备控制结果信息
     */
    @Override
    @Transactional
    public DeviceCommandVO control(DevicesControlDto devicesControlDto) {
        // 创建命令记录
        DeviceCommands deviceCommand = new DeviceCommands();
        deviceCommand.setDeviceId(devicesControlDto.getDeviceId());
        deviceCommand.setCommandType(devicesControlDto.getCommandType());
        deviceCommand.setCommandData(devicesControlDto.getCommandData().toString());
        deviceCommand.setStatus("PENDING");
        deviceCommand.setCreatedTime(LocalDateTime.now());

        // 保存命令到数据库
        deviceCommandsService.save(deviceCommand);

        // 发送MQTT消息
        JSONObject commandData = devicesControlDto.getCommandData();
        MqttMessage mqttMessage = new MqttMessage(commandData.toString().getBytes());
        mqttMessage.setQos(1);
        try {
            mqttClient.publish(devicesControlDto.getDeviceId(), mqttMessage);
            // 更新命令状态为已发送
            deviceCommand.setStatus("SENT");
            deviceCommand.setSentTime(LocalDateTime.now());
            deviceCommandsService.updateById(deviceCommand);
        } catch (MqttException e) {
            // 发送失败，更新命令状态为失败
            deviceCommand.setStatus("FAILED");
            deviceCommandsService.updateById(deviceCommand);
            throw new RuntimeException("发送MQTT消息失败: " + e.getMessage(), e);
        }

        // 返回VO对象
        DeviceCommandVO vo = new DeviceCommandVO();
        vo.setId(deviceCommand.getId());
        // 根据字符串状态设置枚举状态
        String status = (String) deviceCommand.getStatus();
        if ("PENDING".equals(status)) {
            vo.setStatus(DeviceCommandVO.CommandStatus.PENDING);
        } else if ("SENT".equals(status)) {
            vo.setStatus(DeviceCommandVO.CommandStatus.SENT);
        } else if ("EXECUTED".equals(status)) {
            vo.setStatus(DeviceCommandVO.CommandStatus.EXECUTED);
        } else if ("FAILED".equals(status)) {
            vo.setStatus(DeviceCommandVO.CommandStatus.FAILED);
        }
        vo.setDeviceId(deviceCommand.getDeviceId());
        vo.setCommandType(deviceCommand.getCommandType());
        vo.setCommandData(deviceCommand.getCommandData());
        vo.setCreatedTime(deviceCommand.getCreatedTime());
        vo.setSentTime(deviceCommand.getSentTime());
        return vo;
    }
}




